#!/bin/bash
export PATH="/usr/bin:/usr/sbin:${PATH}"
set -euo pipefail

. /usr/lib/coreos/generator-lib.sh

# Turn out if you boot with "root=..." $UNIT_DIR is not writable.
[ -w "${UNIT_DIR}" ] || {
    echo "skipping coreos-boot-mount-generator: ${UNIT_DIR} is not writable"
    exit 0
}

# If there's already an /etc/fstab entries for /boot, then this is is a non-FCOS
# system, likely RHCOS pre-4.3 (which still used Anaconda).  In that case, we
# don't want to overwrite what the systemd-fstab-generator will do.
if findmnt --fstab /boot &>/dev/null; then
    exit 0
fi

# Don't create mount units for /boot on live systems.
# ConditionPathExists won't work here because conditions don't affect
# the dependency on the underlying device unit.
if [ -f /run/ostree-live ]; then
    exit 0
fi

add_wants() {
    local name="$1"; shift
    local wants_dir="${UNIT_DIR}/local-fs.target.wants"
    mkdir -p "${wants_dir}"
    ln -sf "../${name}" "${wants_dir}/${name}"
}

# Generate mount units that work with device mapper. The traditional
# device unit (dev-disk-by\x2dlabel...) does not work since it is not the
# device that systemd will fsck. This code ensures that if the label
# is backed by a device-mapper target the dev-mapper.*.device is used.
mk_mount() {
    local mount_pt="${1}"; shift
    local path="${1}"; shift
    local options="${1}"; shift

    local devservice=$(systemd-escape -p ${path} --suffix=service)
    local unit_name=$(systemd-escape -p ${mount_pt} --suffix=mount)

    cat > "${UNIT_DIR}/${unit_name}" <<EOF
# Automatically created by coreos-boot-mount-generator
[Unit]
Description=CoreOS Dynamic Mount for ${mount_pt}
Documentation=https://github.com/coreos/fedora-coreos-config

Before=local-fs.target
Requires=systemd-fsck@${devservice}
After=systemd-fsck@${devservice}

[Mount]
What=${path}
Where=${mount_pt}
Options=${options}
EOF
    add_wants "${unit_name}"
}

# If the root device is multipath, hook up /boot to use that too,
# based on our custom udev rules in 90-coreos-device-mapper.rules
# that creates "label found on mpath" links.
# Otherwise, use the usual by-label symlink.
bootdev=/dev/disk/by-label/boot
# TODO add equivalent of getargbool() so we handle rd.multipath=0
if have_karg rd.multipath; then
    bootdev=/dev/disk/by-label/dm-mpath-boot
fi

# We mount read-only by default mostly to protect
# against accidental damage.  Only a few things
# owned by CoreOS should be touching /boot or the ESP.
# Use nodev,nosuid because some hardening guides want
# that even though it's of minimal value.
mk_mount /boot "${bootdev}" ro,nodev,nosuid
